const fs = require('fs')
const EventEmitter = require('events')

class MyFileReadStream extends EventEmitter{
  constructor(path, options = {}){
    super()
    this.path = path
    this.flags = options.flags || "r"
    this.mode = options.mode || 438
    this.autoClose = options.autoClose || true
    this.start = options.start || 0
    this.end = options.end
    this.highWaterMark = options.highWaterMark || 64*1024
    this.readOffset = 0

    this.open()
    this.on('newListener',(type)=>{
      if(type==='data'){
        this.read()
      }
    })
  }

  open(){
    // 使用原生open方法打开文件
    fs.open(this.path, this.flags, this.mode, (err,fd)=>{
      if(err){
        this.emit('error',err)
      }
      this.fd = fd
      this.emit('open',fd)
    })
  }
  read(){
    // fd不为数值，表示open方法读取文件中(异步行为)
    if(typeof this.fd !== 'number'){
      // open事件响应 递归调用 以调整代码执行顺序
      return this.once('open', this.read)
    }

    let buf = Buffer.alloc(this.highWaterMark)

    let howMuchToRead
    if(this.end){
      howMuchToRead = Math.min(this.end-this.readOffset+1,this.highWaterMark)
    } else {
      howMuchToRead = this.highWaterMark
    }

    fs.read(this.fd, buf, 0, howMuchToRead, this.readOffset, (err,readBytes)=>{
      if(readBytes){//readBytes有值表示读取到了数据内容
        this.readOffset += readBytes
        this.emit('data', buf.slice(0, readBytes))
        this.read()
      }else{
        this.emit('end')
        this.close()
      }
    })
  }
  close(){
    fs.close(this.fd, ()=>{
      this.emit('close')
    })
  }
  pipe(ws){
    this.on('data',(data)=>{
      let flag = ws.write(data)
      if(!flag){
        // 意思一下，不会触发，触发就报错了
        this.pause()
      }
    })
    // 意思一下，不会触发，触发就报错了
    ws.on('drain',()=>{
      this.resume()
    })
  }
}

module.exports = MyFileReadStream
